#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QNetworkDatagram>
const int PORT=8000;
//const QString IP="127.0.0.1";

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    socket=new QUdpSocket(this);
    //设置窗口标题
    this->setWindowTitle("服务端");
    //连接信号槽(接收缓冲区有数据，就发送信号，执行槽函数)
    connect(socket,&QUdpSocket::readyRead,this,&Widget::processRequest);

    //一旦绑定端口号那么就可以收到客户端的请求了，可能会出现绑定之前消息收不到
    //所以先连接信号槽，后绑定端口号
    bool ret= socket->bind(QHostAddress::Any,PORT);
    //端口号的合法有限范围是2字节大小整形

    //提示错误信息   errorString----perror,本质都是对errno进行封装
    if(!ret){
        QMessageBox::critical(this,"服务器启动失败",socket->errorString());
        return ;
    }

}

Widget::~Widget()
{
    delete ui;
}

//槽函数
void Widget::processRequest(){
    //1.读取客户端数据
    //读取网络数据报(报头+报文)--网络字节序
    const QNetworkDatagram& requestDatagram=socket->receiveDatagram();
    //从数据报中拿出来报文(网络字节流):指定编码,例子：序列化后汉字乱码，需要指定编码
    //获取字节流数组
    auto byteArray=requestDatagram.data();
    //将字节流数组转化为字符串数组
    QString request=QString::fromUtf8(byteArray);

    //2.根据数据计算响应的数据报文
    const QString response=process(request);
    //3.把响应回显给客户端--构建数据包
    QNetworkDatagram responseDatagram(response.toUtf8(),requestDatagram.senderAddress(),
                                      requestDatagram.senderPort());
    //发送数据包给客户端
    socket->writeDatagram(responseDatagram);
    //格式   [ip：port]正文
    QString log="["+requestDatagram.senderAddress().toString()+"："+QString::number(requestDatagram.senderPort())
            +"]"+"request："+request+"  response："+response;
    //添加一行数据
    ui->listWidget->addItem(log);

}

QString Widget::process(const QString &request){
    //回显服务器
    return request;
}


